home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_191 / ispell / src.zoo / good.c < prev    next >
C/C++ Source or Header  |  1989-02-22  |  14KB  |  780 lines

  1. /* -*- Mode:Text -*- */
  2.  
  3. /*
  4.  * good.c - see if a word or its root word
  5.  * is in the dictionary.
  6.  *
  7.  * Pace Willisson, 1983
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "config.h"
  13. #include "ispell.h"
  14.  
  15. extern struct dent *lookup();
  16. extern char *index();
  17.  
  18. static int wordok;
  19. static char *orig_word;
  20.  
  21. extern int cflag;
  22.  
  23. good (w)
  24. char *w;
  25. {
  26.     char nword[100];
  27.     register char *p, *q;
  28.     register n;
  29.  
  30.     /*
  31.     ** Make an uppercase copy of the word we are checking.
  32.     */
  33.     for (p = w, q = nword; *p; p++, q++) {
  34.         if (mylower (*p))
  35.             *q = toupper (*p);
  36.         else
  37.             *q = *p;
  38.     }
  39.     *q = 0;
  40.  
  41.     rootword[0] = 0;
  42.  
  43.     if (cflag) {
  44.         printf ("%s\n", w);
  45.         orig_word = w;
  46.     }
  47.     else if (lookup (nword, q - nword, 1) != NULL) {
  48. #ifdef CAPITALIZE
  49.         return cap_ok (w, lastdent);
  50. #else
  51.         return (1);
  52. #endif
  53.     }
  54.  
  55.     /* try stripping off suffixes */
  56.  
  57.     n = strlen (w);
  58.     if (n == 1)
  59.         return (1);
  60.  
  61.     if (n < 4)
  62.         return 0;
  63.  
  64.     wordok = 0;
  65.  
  66.     /* this part from 'check.mid' */
  67.     switch (q[-1]) {
  68.     case 'D': d_ending (nword,n); break;    /* FOR "CREATED", "IMPLIED", "CROSSED" */
  69.     case 'T': t_ending (nword,n); break;    /* FOR "LATEST", "DIRTIEST", "BOLDEST" */
  70.     case 'R': r_ending (nword,n); break;    /* FOR "LATER", "DIRTIER", "BOLDER" */
  71.     case 'G': g_ending (nword,n); break;    /* FOR "CREATING", "FIXING" */
  72.     case 'H': h_ending (nword,n); break;    /* FOR "HUNDREDTH", "TWENTIETH" */
  73.     case 'S': s_ending (nword,n); break;    /* FOR ALL SORTS OF THINGS ENDING IN "S" */
  74.     case 'N': n_ending (nword,n); break;    /* "TIGHTEN", "CREATION", "MULIPLICATION" */
  75.     case 'E': e_ending (nword,n); break;    /* FOR "CREATIVE", "PREVENTIVE" */
  76.     case 'Y': y_ending (nword,n); break;    /* FOR "QUICKLY" */
  77.     default:
  78.         break;
  79.     }
  80.     
  81.     if (wordok) {
  82.         strcpy (rootword, lastdent->word);
  83. #ifdef CAPITALIZE
  84.         return cap_ok (w, lastdent);
  85. #else
  86.         return 1;
  87. #endif
  88.     }
  89.     return 0;
  90. }
  91.  
  92. #ifdef CAPITALIZE
  93. cap_ok (word, dent)
  94. register char *word;
  95. register struct dent *dent;
  96. {
  97.     register char *dword;
  98.     register char *w;
  99.     int wcount;
  100.  
  101.     /*
  102.     ** All caps is always legal.
  103.     */
  104.     for (dword = word;  *dword;  dword++) {
  105.         if (mylower (*dword))
  106.             break;
  107.     }
  108.     if (*dword == '\0')
  109.         return 1;        /* It was all caps */
  110.     if (dent->allcaps)
  111.         return 0;        /* Not all caps and required to be */
  112.     if (dent->followcase) {
  113.         /*
  114.         ** It's a followcase word.  The correct capitalizations are
  115.         ** found following the main dent word.  When we find a
  116.         ** mismatch between letters, we assume we are in the suffix,
  117.         ** and begin insisting on the same case as the last letter
  118.         ** that matched.
  119.         */
  120.         dword = dent->word + strlen (dent->word) + 1;
  121.         wcount = *dword++ & 0xFF;
  122.         while (--wcount >= 0) {
  123.             dword++;            /* Skip over keep flag */
  124.             for (w = word;  *w;  w++, dword++) {
  125.             if (*dword != *w) {
  126.                 /* Begin suffix processing.  */
  127.                 if (myupper (dword[-1])) {
  128.                 while (*w  &&  !mylower (*w))
  129.                     w++;
  130.                 if (*w == '\0')
  131.                     return 1;
  132.                 }
  133.                 else {
  134.                 while (*w  &&  !myupper (*w))
  135.                     w++;
  136.                 if (*w == '\0')
  137.                     return 1;
  138.                 }
  139.                 break;
  140.             }
  141.             }
  142.             if (*w == '\0')
  143.             return 1;
  144.             while (*dword++)    /* Skip to next prototype */
  145.             ;
  146.         }
  147.     }
  148.     /*
  149.     ** If it's a capitalize word, and the first letter is lowercase,
  150.     ** it's illegal.  Note that all-lowercase followcase words will
  151.     ** be found by the string scan above.
  152.     */
  153.     if (dent->capitalize  &&  mylower (*word))
  154.         return 0;
  155.     /*
  156.     ** If it's not a followcase word, or if the capitalize flag is set,
  157.     ** capitalization (e.g. at the beginning of a sentence) is always
  158.     ** legal.  All-lowercase is also legal for non-followcase words.
  159.     */
  160.     if (!dent->followcase  ||  dent->capitalize) {
  161.         for (dword = word + 1;  *dword;  dword++) {
  162.             if (myupper (*dword))
  163.                 break;
  164.         }
  165.         if (*dword == '\0')
  166.             return 1;    /* It was all-lower or capitalized */
  167.     }
  168.     return 0;            /* Word has a bad mix of cases */
  169. }
  170. #endif
  171.  
  172. flagpr (w, flag, modpoint)
  173. register char *w;
  174. int flag;
  175. register char *modpoint;    /* Must be in w and greater than w */
  176. {
  177.     register char *orig;
  178.  
  179.     /*
  180.     ** We refuse to print if the case at and after modpoint isn't
  181.     ** consistent with the case just before there.  This prevents
  182.     ** things like "OEM's" from being turned into OEM/M, which in
  183.     ** turn will only accept "OEM'S".
  184.     */
  185.     orig = orig_word + (modpoint - w);
  186.     if (myupper(orig[-1])) {
  187.         while (*orig) {
  188.             if (mylower (*orig++))
  189.                 return;
  190.         }
  191.     }
  192.     else {
  193.         while (*orig) {
  194.             if (myupper (*orig++))
  195.                 return;
  196.         }
  197.     }
  198.     /* Case is ok.  Now print it. */
  199.     for (orig = orig_word;  *w  &&  w < modpoint;  orig++, w++)
  200.         putchar (*orig);
  201.     if (myupper (orig[-1]))
  202.         printf ("%s", w);
  203.     else {
  204.         for (  ;  *w;  w++) {
  205.             if (myupper (*w))
  206.                 putchar (tolower (*w));
  207.             else
  208.                 putchar (*w);
  209.         }
  210.     }
  211.     printf ("/%c\n", flag);
  212. }
  213.  
  214. g_ending (w,n)
  215. register char *w;
  216. register int n;
  217. {
  218.     register char *p;
  219.     register struct dent *dent;
  220.  
  221.     p = w + n - 3;    /* if the word ends in 'ing', then *p == 'i' */
  222.     
  223.     if (strcmp (p, "ING") != 0)
  224.         return;
  225.  
  226.     *p = 'E';    /* change I to E, like in CREATING */
  227.     *(p+1) = 0;
  228.     n -= 2;
  229.  
  230.     if (n < 2)
  231.         return;
  232.  
  233.     if (cflag)
  234.         flagpr (w, 'G', p);
  235.     else if ((dent = lookup (w, n, 1)) != NULL
  236.       &&  dent->g_flag) {
  237.         wordok = 1;
  238.         return;
  239.     }
  240.  
  241.  
  242.     *p = 0;
  243.     n--;
  244.  
  245.     if (n < 2)
  246.         return;
  247.  
  248.     if (p[-1] == 'E')
  249.         return;    /* this stops CREATEING */
  250.  
  251.     if (cflag)
  252.         flagpr (w, 'G', p);
  253.     else if ((dent = lookup (w, n, 1)) != NULL) {
  254.         if (dent->g_flag)
  255.             wordok = 1;
  256.         return;
  257.     }
  258.     return;
  259. }
  260.  
  261. d_ending (w,n)
  262. register char *w;
  263. register n;
  264. {
  265.     register char *p;
  266.     register struct dent *dent;
  267.  
  268.     p = w + n - 2;
  269.  
  270.     if (strcmp (p, "ED") != 0)
  271.         return;
  272.  
  273.     p[1] = 0;    /* kill 'D' */
  274.     n--;
  275.  
  276.     if (cflag)
  277.         flagpr (w, 'D', p + 1);
  278.     else if ((dent = lookup (w, n, 1)) != NULL) { /* eg CREATED */
  279.         if (dent->d_flag) {
  280.             wordok = 1;
  281.             return;
  282.         }
  283.     }
  284.  
  285.     if (n < 3)
  286.         return;
  287.  
  288.     p[0] = 0;
  289.     n--;
  290.     p--;
  291.  
  292.     /* ED is now completely gone */
  293.  
  294.     if (p[0] == 'I' && !vowel (p[-1])) {
  295.         p[0] = 'Y';
  296.         if (cflag)
  297.             flagpr (w, 'D', p);
  298.         else if ((dent = lookup (w, n, 1)) != NULL
  299.             &&  dent->d_flag) {
  300.             wordok = 1;
  301.             return;
  302.         }
  303.         p[0] = 'I';
  304.     }
  305.  
  306.     if ((p[0] != 'E' && p[0] != 'Y') ||
  307.         (p[0] == 'Y' && vowel (p[-1]))) {
  308.         if (cflag)
  309.             flagpr (w, 'D', p + 1);
  310.         else if ((dent = lookup (w, n, 1)) != NULL) {
  311.             if (dent->d_flag)
  312.                 wordok = 1;
  313.             return;
  314.         }
  315.     }
  316. }
  317.  
  318. t_ending (w,n)
  319. register char *w;
  320. register n;
  321. {
  322.  
  323.     register char *p;
  324.     register struct dent *dent;
  325.  
  326.     p = w + n - 3;
  327.  
  328.     if (strcmp (p, "EST") != 0)
  329.         return;
  330.  
  331.     p[1] = 0;    /* kill "ST" */
  332.     n -= 2;
  333.  
  334.     if (cflag)
  335.         flagpr (w, 'T', p);
  336.     else if ((dent = lookup (w, n, 1)) != NULL
  337.         &&  dent->t_flag) {
  338.         wordok = 1;
  339.         return;
  340.     }
  341.  
  342.     if (n < 3)
  343.         return;
  344.  
  345.     p[0] = 0;    /* kill 'E' */
  346.     n--;
  347.     p--;
  348.  
  349.     /* EST is now completely gone */
  350.  
  351.     if (p[0] == 'I' && !vowel (p[-1])) {
  352.         p[0] = 'Y';
  353.         if (cflag)
  354.             flagpr (w, 'T', p);
  355.         else if ((dent = lookup (w, n, 1)) != NULL
  356.             &&  dent->t_flag) {
  357.             wordok = 1;
  358.             return;
  359.         }
  360.         p[0] = 'I';
  361.     }
  362.  
  363.     if ((p[0] != 'E' && p[0] != 'Y') ||
  364.         (p[0] == 'Y' && vowel (p[-1]))) {
  365.         if (cflag)
  366.             flagpr (w, 'T', p + 1);
  367.         else if ((dent = lookup (w, n, 1)) != NULL) {
  368.             if (dent->t_flag)
  369.                 wordok = 1;
  370.             return;
  371.         }
  372.     }
  373.  
  374. }
  375.  
  376.  
  377. r_ending (w,n)
  378. register char *w;
  379. register n;
  380. {
  381.     register char *p;
  382.     register struct dent *dent;
  383.  
  384.     p = w + n - 2;
  385.  
  386.     if (strcmp (p, "ER") != 0)
  387.         return;
  388.  
  389.     p[1] = 0;    /* kill 'R' */
  390.     n--;
  391.  
  392.     if (cflag)
  393.         flagpr (w, 'R', p + 1);
  394.     else if ((dent = lookup (w, n, 1)) != NULL
  395.         &&  dent->r_flag) {
  396.         wordok = 1;
  397.         return;
  398.     }
  399.  
  400.     if (n < 3)
  401.         return;
  402.  
  403.     p[0] = 0;    /* kill 'E' */
  404.     n--;
  405.     p--;
  406.  
  407.     /* ER is now completely gone */
  408.  
  409.     if (p[0] == 'I' && !vowel (p[-1])) {
  410.         p[0] = 'Y';
  411.         if (cflag)
  412.             flagpr (w, 'R', p);
  413.         else if ((dent = lookup (w, n, 1)) != NULL
  414.             &&  dent->r_flag) {
  415.             wordok = 1;
  416.             return;
  417.         }
  418.         p[0] = 'I';
  419.     }
  420.  
  421.     if ((p[0] != 'E' && p[0] != 'Y') ||
  422.         (p[0] == 'Y' && vowel (p[-1]))) {
  423.         if (cflag)
  424.             flagpr (w, 'R', p + 1);
  425.         else if ((dent = lookup (w, n, 1)) != NULL) {
  426.             if (dent->r_flag)
  427.                 wordok = 1;
  428.             return;
  429.         }
  430.     }
  431.  
  432. }
  433.  
  434. h_ending (w,n)
  435. register char *w;
  436. register n;
  437. {
  438.     register char *p;
  439.     register struct dent *dent;
  440.  
  441.     p = w + n - 2;
  442.  
  443.     if (strcmp (p, "TH") != 0)
  444.         return;
  445.  
  446.     *p = 0;        /* kill "TH" */
  447.     n -= 2;
  448.  
  449.     p -= 2;
  450.  
  451.     if (p[1] != 'Y') {
  452.         if (cflag)
  453.             flagpr (w, 'H', p + 2);
  454.         else if ((dent = lookup (w, n, 1)) != NULL
  455.             &&  dent->h_flag)
  456.             wordok = 1;
  457.     }
  458.  
  459.     if (strcmp (p, "IE") != 0)
  460.         return;
  461.  
  462.     p[0] = 'Y';    /* change "IE" to "Y" */
  463.     p[1] = 0;
  464.     n--;
  465.  
  466.     if (cflag)
  467.         flagpr (w, 'H', p + 1);
  468.     else if ((dent = lookup (w, n, 1)) != NULL)
  469.         if (dent->h_flag)
  470.             wordok = 1;
  471.  
  472. }
  473.  
  474. /*
  475.  * check for flags: X, J, Z, S, P, M
  476.  *
  477.  * X    -ions or -ications or -ens
  478.  * J    -ings
  479.  * Z    -ers or -iers
  480.  * S    -ies or -es or -s
  481.  * P    -iness or -ness
  482.  * M    -'S
  483.  */
  484.  
  485. s_ending (w,n)
  486. register char *w;
  487. register n;
  488. {
  489.     register char *p;
  490.     register struct dent *dent;
  491.  
  492.     p = w + n;
  493.  
  494.     p[-1] = 0;    /* kill 'S' */
  495.     n--;
  496.  
  497.     if (index ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y' && vowel (p[-3]))) {
  498.         if (cflag)
  499.             flagpr (w, 'S', p - 1);
  500.         else if ((dent = lookup (w, n, 1)) != NULL
  501.             &&  dent->s_flag) {
  502.             wordok = 1;
  503.             return;
  504.         }
  505.     }
  506.  
  507.  
  508.     switch (p[-2]) {    /* letter before S */
  509.     case 'N':    /* X */
  510.         if (strcmp (p-4, "ION") == 0) {
  511.             p[-4] = 'E';    /* change "ION" to "E" */
  512.             p[-3] = 0;
  513.             n -= 2;
  514.             if (cflag)
  515.                 flagpr (w, 'X', p - 4);
  516.             else if ((dent = lookup (w, n, 1)) != NULL
  517.               &&  dent->x_flag) {
  518.                 wordok = 1;
  519.                 return;
  520.             }
  521.         }
  522.         if (strcmp (p-8, "ICATE") == 0) {
  523.             p[-8] = 'Y';    /* change "ICATE" to "Y" */
  524.             p[-7] = 0;
  525.             n -= 4;
  526.             if (cflag)
  527.                 flagpr (w, 'X', p - 8);
  528.             else if ((dent = lookup (w, n, 1)) != NULL
  529.                 && dent->x_flag)
  530.                 wordok = 1;
  531.             return;
  532.         }
  533.         if (strcmp (p-3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y') {
  534.             p[-3] = 0;    /* kill "EN" */
  535.             n -= 2;
  536.             if (cflag)
  537.                 flagpr (w, 'X', p - 3);
  538.             else if ((dent = lookup (w, n, 1)) != NULL
  539.                 && dent->x_flag)
  540.                 wordok = 1;
  541.             return;
  542.         }
  543.         return;
  544.     case 'G':    /* J */
  545.         if (strcmp (p-4, "ING") != 0)
  546.             return;
  547.         p[-4] = 'E';    /* change "ING" to "E" */
  548.         p[-3] = 0;
  549.         n -= 2;
  550.         if (cflag)
  551.             flagpr (w, 'J', p - 4);
  552.         else if ((dent = lookup (w, n, 1)) != NULL
  553.             &&  dent->j_flag) {
  554.             wordok = 1;
  555.             return;
  556.         }
  557.         if (p[-5] == 'E')
  558.             return;        /* This stops CREATEING */
  559.         p[-4] = 0;    /* kill 'E' */
  560.         n--;
  561.         if (cflag)
  562.             flagpr (w, 'J', p - 4);
  563.         else if ((dent = lookup (w, n, 1)) != NULL
  564.             && dent->j_flag)
  565.             wordok = 1;
  566.         return;
  567.     case 'R':    /* Z */
  568.         if (strcmp (p-3, "ER") != 0)
  569.             return;
  570.  
  571.         p[-2] = 0;    /* kill 'R' */
  572.         n--;
  573.         if (cflag)
  574.             flagpr (w, 'Z', p - 2);
  575.         else if ((dent = lookup (w, n, 1)) != NULL
  576.             &&  dent->z_flag) {
  577.             wordok = 1;
  578.             return;
  579.         }
  580.         if (p[-4] == 'I'  &&  !vowel (p[-5])) {
  581.             p[-4] = 'Y';    /* change "IE" to "Y" */
  582.             p[-3] = 0;
  583.             n--;
  584.             if (cflag)
  585.                 flagpr (w, 'Z', p - 4);
  586.             else if ((dent = lookup (w, n, 1)) != NULL
  587.                 && dent->z_flag) {
  588.                 wordok = 1;
  589.                 return;
  590.             }
  591.             p[-4] = 'I';    /* change 'Y' to 'I' */
  592.         }
  593.         if ((p[-4] != 'E' && p[-4] != 'Y') ||
  594.             (p[-4] == 'Y' && vowel (p[-5]))) {
  595.             if(p[-3]) n--;
  596.             p[-3] = 0;
  597.             if (cflag)
  598.                 flagpr (w, 'Z', p - 3);
  599.             else if ((dent = lookup (w, n, 1)) != NULL
  600.               && dent->z_flag)
  601.                 wordok = 1;
  602.         }
  603.         return;
  604.     case 'E': /* S (except simple adding of an S) */
  605.         p[-2] = 0;    /* drop the E */
  606.         n--;
  607.         if (index ("SXZH", p[-3]) != NULL) {
  608.             if (cflag)
  609.                 flagpr (w, 'S', p - 2);
  610.             else if ((dent = lookup (w, n, 1)) != NULL) {
  611.                 if (dent->s_flag)
  612.                     wordok = 1;;
  613.                 return;
  614.             }
  615.         }
  616.         if (p[-3] == 'I'  &&  !vowel (p[-4])) {
  617.             p[-3] = 'Y';
  618.             if (cflag)
  619.                 flagpr (w, 'S', p - 3);
  620.             else if ((dent = lookup (w, n, 1)) != NULL
  621.                 && dent->s_flag)
  622.                 wordok = 1;
  623.             return;
  624.         }
  625.         return;
  626.  
  627.     case 'S':    /* P */
  628.         if (strcmp (p-4, "NES") != 0)
  629.             return;
  630.  
  631.         p[-4] = 0;    /* kill "NES" */
  632.         n -= 3;
  633.         if (p[-5] != 'Y' || vowel (p[-6])) {
  634.             if (cflag)
  635.                 flagpr (w, 'P', p - 4);
  636.             else if ((dent = lookup (w, n, 1)) != NULL
  637.                 &&  dent->p_flag) {
  638.                 wordok = 1;
  639.                 return;
  640.             }
  641.         }
  642.         if (p[-5] == 'I') {
  643.             p[-5] = 'Y';
  644.             if (cflag)
  645.                 flagpr (w, 'P', p - 5);
  646.             else if ((dent = lookup (w, n, 1)) != NULL
  647.                 && dent->p_flag)
  648.                 wordok = 1;
  649.         }
  650.         return;
  651.     case '\'':    /* M */
  652.         p[-2] = '\0';    /* kill "'" */
  653.         n--;
  654.         if (cflag)
  655.             flagpr (w, 'M', p - 2);
  656.         else if ((dent = lookup (w, n, 1)) != NULL
  657.             &&  dent->m_flag)
  658.             wordok = 1;
  659.         return;
  660.     }
  661. }
  662.  
  663. /* only the N flag */
  664. n_ending (w,n)
  665. register char *w;
  666. register n;
  667. {
  668.     register char *p;
  669.     register struct dent *dent;
  670.  
  671.     p = w + n;
  672.  
  673.     if (p[-2] == 'E') {
  674.         if (p[-3] == 'E' || p[-3] == 'Y')
  675.             return;
  676.         p[-2] = 0;    /* kill "EN" */
  677.         n -= 2;
  678.         if (cflag)
  679.             flagpr (w, 'N', p - 2);
  680.         else if ((dent = lookup (w, n, 1)) != NULL
  681.             && dent->n_flag)
  682.             wordok = 1;
  683.         return;
  684.     }
  685.  
  686.     if (strcmp (p-3, "ION") != 0)
  687.         return;
  688.  
  689.     p[-3] = 'E';    /* change "ION" to "E" */
  690.     p[-2] = 0;
  691.     n -= 2;
  692.  
  693.     if (cflag)
  694.         flagpr (w, 'N', p - 3);
  695.     else if ((dent = lookup (w, n, 1)) != NULL) {
  696.         if (dent->n_flag)
  697.             wordok = 1;
  698.         return;
  699.     }
  700.  
  701.     if (strcmp (p-7, "ICATE") != 0)    /* check is really against "ICATION" */
  702.         return;
  703.  
  704.     p[-7] = 'Y';    /* change "ICATE" to "Y" */
  705.     p[-6] = 0;
  706.     n -= 4;
  707.     
  708.     if (cflag)
  709.         flagpr (w, 'N', p - 7);
  710.     else if ((dent = lookup (w, n, 1)) != NULL && dent->n_flag)
  711.         wordok = 1;
  712.     return;
  713. }
  714.  
  715. /* flags: v */
  716. e_ending (w,n)
  717. register char *w;
  718. register n;
  719. {
  720.     register char *p;
  721.     register struct dent *dent;
  722.  
  723.     p = w + n;
  724.  
  725.     if (strcmp (p-3, "IVE") != 0)
  726.         return;
  727.     p[-3] = 'E';    /* change "IVE" to "E" */
  728.     p[-2] = 0;
  729.     n -= 2;
  730.  
  731.     if (cflag)
  732.         flagpr (w, 'V', p - 3);
  733.     else if ((dent = lookup (w, n, 1)) != NULL
  734.       &&  dent->v_flag) {
  735.         wordok = 1;
  736.         return;
  737.     }
  738.  
  739.     if (p[-4] == 'E')
  740.         return;
  741.  
  742.     p[-3] = 0;    /* kill 'E' */
  743.     n--;
  744.  
  745.     if (cflag)
  746.         flagpr (w, 'V', p - 3);
  747.     else if ((dent = lookup (w, n, 1)) != NULL && dent->v_flag)
  748.         wordok = 1;
  749.     return;
  750. }
  751.  
  752. /* flags: y */
  753. y_ending (w,n)
  754. register char *w;
  755. register n;
  756. {
  757.     register char *p;
  758.     register struct dent *dent;
  759.  
  760.     p = w + n;
  761.  
  762.     if (strcmp (p-2, "LY") != 0)
  763.         return;
  764.  
  765.     p[-2] = 0;    /* kill "LY" */
  766.     n -= 2;
  767.  
  768.     if (cflag)
  769.         flagpr (w, 'Y', p - 2);
  770.     else if ((dent = lookup (w, n, 1)) != NULL && dent->y_flag)
  771.         wordok = 1;
  772.     return;
  773. }
  774.  
  775. vowel (c)
  776. register c;
  777. {
  778.     return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
  779. }
  780.